/*
 *  translator.c
 *  
 *
 *  Created by Yi Lin on 11-5-6.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */
/*
 *  translator.h
 *  
 *
 *  Created by Yi Lin on 11-5-6.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "internal.h"
#include <stdio.h>
#include <stdlib.h>

int translate_tactics (struct translationunit *unit){
        translate_translation_unit(unit);
        return 0;
}

int translate_translation_unit(struct translationunit *unit){
	if (unit == NULL) {
		return -1;
	}
	
        printf("#include <stdio.h> \n");
        printf("#include <stdlib.h> \n");
        printf("#include \"tacticlib.h\" \n");
        
        translate_enumeration_list(unit->e);
        
        printf("int main (char** args, int* argv) {\n" );
        printf("initialize_enumerations();\n\n");
        printf("}\n");
        
        return 0;
}

/* translate the enumeration's definitions*/
int translate_enumeration_list(struct e_list *list) {
        
        struct e_node *p = list->first;
        
        for (; p != NULL; p = p->next) {
                translate_enumeration(p->enumerate); 
        }
        
        /* sample:
         initialize_enumerations(){
         intialize_enum_player();
         }
         */
        
        printf ("initialize_enumerations() {\n");
        
        p = list->first;
        for (; p != NULL; p = p->next) {
                printf("initialize_enum_%s ();\n", p->enumerate->identifier);
        }
        
        printf("}\n");
        
}

int translate_enumeration(struct e_enumerate *enumerate) {
        
        
        /* example:
         
         initialize_enum_player(){
         player.e = (struct enum_element *)malloc(sizeof(struct enum_element) * player->count);
         player.e[player1].value = 1;
         player.e[player1].sequence = 1;
         player.e[player1].desc = "test";
         player.e[player1].identifier = "player1";
         palyer.e[player1].declaration = &palyer;
         }         
         */
        
        char *id = enumerate->identifier;
        printf("struct enum_declaration %s; \n", id);
        
        if (enumerate->cate == E_BASE) {
                struct e_elemnode *p = enumerate->spec.base.elemlist->first;
                
                int enum_count = 0;
                while (p != NULL) {
                        
                        struct e_element *e = p->element;
                        printf("int %s = %d; \n", e->identifier, enum_count);
                        
                        enum_count ++;
                        p = p->next;
                }
        }
        
        printf("initialize_enum_%s(){\n", id);
        
        printf("%s.e = (struct enum_element *)"
               "malloc(sizeof(struct enum_element) * %s.count); \n",  id, id);
        printf("\n");
        
        printf("/* element(s) of enumeration %s */ \n", id);
        
        if (enumerate->cate == E_BASE) {
                struct e_elemnode *p = enumerate->spec.base.elemlist->first;
                
                int enum_count = 0;
                
                while (p != NULL) {
                        struct e_element *e = p->element;
                        e->sequence = enum_count;
                        p = p->next;
                        printf("%s.e[%s].value = %d; \n", id, e->identifier, e->value);
                        printf("%s.e[%s].sequence = %d; \n", id, e->identifier, e->sequence);
                        printf("%s.e[%s].desc = \"%s\"; \n", id, e->identifier, e->desc);
                        printf("%s.e[%s].identifier = \"%s\"; \n", id, e->identifier, e->identifier);
                        printf("%s.e[%s].declaration = &%s; \n", id, e->identifier, id);
                        printf("\n");
                        enum_count ++;
                }
                
        }
        
        printf("}\n\n");
        
}

/* translate argument's declarations*/
int translate_argument_list()

int main(char ** argv, int *argc) {
        struct translationunit unit;
        struct e_list list;
        struct e_elemlist elemlist;
        struct e_element element;
        struct e_enumerate enumerate;
        struct e_node node;
        struct e_elemnode elemnode;
        
        unit.e = &list;
        list.count = 1;
        list.first = &node;
        node.enumerate = &enumerate;
        node.next = NULL;
        enumerate.identifier = "test";
        enumerate.cate = E_BASE;
        enumerate.spec.base.elemlist = &elemlist;
        elemlist.count = 1;
        elemlist.first = &elemnode;
        elemnode.element = &element;
        elemnode.next = NULL;
        element.identifier = "test1";
        element.value = 1;
        element.sequence = 1;
        element.desc = "fortest";
        
        translate_translation_unit(&unit);
        
}